package com.power.config;

import com.power.contant.BussinessEnum;
import com.power.contant.ResourceConstants;
import com.power.filiter.TokenTransferFilter;
import com.power.model.Result;
import com.power.util.JSONUtils;
import com.power.util.ResponseUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.annotation.Resource;

/**
 * security 安全框架的资源服务器
 * 醒项目中一旦加入security 依赖，当前项目就要验证身份
 * 为了获取当前Security识别的的用户的信息对象（就不用去验证用户名和密码了）
 */

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true) //开启@PreAuthorize
public class ResourceServiceConfig extends WebSecurityConfigurerAdapter {

    @Resource
    private TokenTransferFilter tokenTransferFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //关闭跨站伪造请求
        http.csrf().disable();
        //关闭跨域
        http.cors().disable();
        //禁用session机制
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        //添加一个token 转换过滤器在Security安全认证框架用户身份过滤器之前之前
        http.addFilterBefore(tokenTransferFilter, UsernamePasswordAuthenticationFilter.class);

        //异常处理
        http.exceptionHandling()
                .accessDeniedHandler(accessDeniedHandler())//处理携带token 但是全新不足的情况
                .authenticationEntryPoint(authenticationEntryPoint()); //请求为携带token
        //其他请求 也需要进行身份验证
        http.authorizeHttpRequests()
                .antMatchers(ResourceConstants.RESOURCE_ALLOW_URLS).permitAll()// 对Swagger接口不需要进行验证
                .anyRequest().authenticated();

    }

    /**
     * 处理携带token 但是全新不足的情况
     * @return
     */

    @Bean
    public AccessDeniedHandler accessDeniedHandler(){
        return (request, response, accessDeniedException) -> {
            Result<Object> result = Result.fail(BussinessEnum.ACCESS_DENY);
            //响应给前端
            ResponseUtils.write(response, JSONUtils.objToJson(result));
        };
    }

    /**
     * 请求为携带token
     * @return
     */

    @Bean
    public AuthenticationEntryPoint authenticationEntryPoint(){
        return (request, response, authException) -> {
            Result<Object> result = Result.fail(BussinessEnum.UN_AUTHORIZATION);
            //响应给前端
            ResponseUtils.write(response, JSONUtils.objToJson(result));
        };
    }
}
